
package com.trydofor.a9task.base.seq.help;

import com.trydofor.a9task.base.code.help.CodeHelp;
import com.trydofor.a9task.base.code.sysd.Bool;
import com.trydofor.a9task.base.seq.bean.Seq;
import com.trydofor.a9task.base.seq.bean.SeqRw;
import com.trydofor.aloe.assistant.RangeNum;
import static com.trydofor.aloe.character.StringSb.format;
import com.trydofor.aloe.exception.Exceptions;

/**
 * @author : Shi Rongjiu (www.trydofor.com)
 * @date : Dec 11, 2012
 * @see :
 */

public final class SeqBuilder {
    
    public static SeqBuilder seq(long id) {
        return new SeqBuilder(id);
    }
    
    private final SeqRw       seq;
    private transient boolean isDone = false;
    
    private SeqBuilder(long id) {
        seq = new SeqRw();
        seq.setId(id);
        seq.setRecycling(Bool.$FALSE);
    }
    
    public SeqBuilder range(long start, long endup, long inrsm) {
        Exceptions.checkIllegalState(isDone, "can not set when it's done");
        if (!RangeNum.to(start, endup, inrsm)) {
            throw new IllegalArgumentException(format("%s + %s can not reach %s", start,inrsm, endup));
        }
        seq.setStartWith(start);
        seq.setEndupWith(endup);
        seq.setIncrement(inrsm);
        seq.setNextValue(start);
        return this;
    }
    
    public SeqBuilder recyling(boolean isRecyliing) {
        Exceptions.checkIllegalState(isDone, "can not set when it's done");
        seq.setRecycling(CodeHelp.bool(isRecyliing));
        return this;
    }
    
    public SeqBuilder nextValue(long val) {
        Exceptions.checkIllegalState(isDone, "can not set when it's done");
        if (!RangeNum.in(seq.getStartWith(), seq.getEndupWith(), val)) {
            throw new IllegalArgumentException(format("%s not in [%s,%s]", val, seq.getStartWith(), seq.getEndupWith()));
        }
        
        seq.setNextValue(val);
        return this;
    }
    
    public Seq done() {
        isDone = true;
        return seq;
    }
}
